from django.http import FileResponse
from rest_framework.exceptions import APIException
from rest_framework.views import exception_handler
from rest_framework.serializers import ValidationError
from rest_framework.response import Response
from rest_framework import status


class BaseExcept(APIException):

    def __init__(self, detail, code=None):
        if detail:
            self.detail = detail
            if code:
                self.detail['code'] = code


class BadRequest(BaseExcept):
    status_code = status.HTTP_400_BAD_REQUEST
    default_detail = {
        "code": 44004,
        "msg": "请求参数错误"
    }

    def __init__(self, _detail=None):
        detail = _detail if _detail else BadRequest.default_detail
        super(BadRequest, self).__init__(detail)


class AuthenticationFailed(BaseExcept):
    status_code = status.HTTP_401_UNAUTHORIZED
    default_detail = {
        "code": 44011,
        "msg": "未授权的资源请求！"
    }

    def __init__(self, _detail=None):
        detail = _detail if _detail else AuthenticationFailed.default_detail
        super(AuthenticationFailed, self).__init__(detail)


class NotFound(BaseExcept):
    status_code = status.HTTP_404_NOT_FOUND
    default_detail = {
        "code": 44044,
        "msg": "请求资源不存在！"
    }

    def __init__(self, _detail=None):
        detail = _detail if _detail else NotFound.default_detail
        super(NotFound, self).__init__(detail)


class Forbidden(BaseExcept):
    status_code = status.HTTP_403_FORBIDDEN
    default_detail = {
        "code": 44033,
        "msg": "无权限访问该资源，请联系管理员确认！"
    }

    def __init__(self, _detail=None):
        detail = _detail if _detail else Forbidden.default_detail
        super(Forbidden, self).__init__(detail)


class ServerError(BaseExcept):
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
    default_detail = {
        "code": 55000,
        "msg": "服务器端错误，请联系管理员"
    }

    def __init__(self, _detail=None):
        detail = _detail if _detail else ServerError.default_detail
        super(ServerError, self).__init__(detail)


class OK(Response):

    def __init__(self, data='', msg='Success'):
        _data = {
            'data': data,
            'msg': msg
        }
        super(OK, self).__init__(_data, status=status.HTTP_200_OK)


class Created(Response):

    def __init__(self, data, msg='资源已创建'):
        _data = {
            'data': data,
            'msg': msg
        }
        super(Created, self).__init__(_data, status=status.HTTP_201_CREATED)


class Deleted(Response):

    def __init__(self, data, msg='资源已删除'):
        _data = {
            'data': data,
            'msg': msg
        }
        super(Deleted, self).__init__(_data, status=status.HTTP_204_NO_CONTENT)


def file_response(path):
    """ 返回文件类型 """
    down_file = open(path, 'rb')
    f_name = path.split('/')[-1]
    response = FileResponse(down_file, filename=f_name, as_attachment=True)
    response['Content-Type'] = 'application/octet-stream'

    return response


def custom_exception_handler(exc, context):
    """
    自定义返回异常模块
    在序列器中处理数据校验在此捕捉
    :param exc:
    :param context:
    :return:
    """
    response = exception_handler(exc, context)
    try:
        if isinstance(exc, ValidationError):
            msg = exc.args[0]
            if isinstance(msg, dict):
                msg = list(msg.values())[0][0]
            data = {'code': 90000, 'msg': msg}
            return Response(data=data, status=status.HTTP_400_BAD_REQUEST)
        else:
            return response
    except Exception as e:
        print(e)
        return response
